﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TestAlbum.Class;
using System.ComponentModel;

namespace TestAlbum
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        #region Variables
        private List<Member> m_memberList = new List<Member>();

        private int shownMemberIndex = 0;
        private int shownMemberPictureIndex = 0;

        Random rdn;
        #endregion
        
        #region Form
        public Window1()
        {
            InitializeComponent();

            rdn = new Random((int)DateTime.Now.Ticks * DateTime.Now.Millisecond);

            LoadLogoData();

            LoadList();
            LoadMainPicture();

            lblDBVersion.Content += Tools.DatabaseVersion;
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    this.Close();
                    break;
            }
        }

        #endregion

        #region Load Member List
        private void LoadList()
        {
            dgvMembers.DataContext = null;
            m_memberList = MemberList.GetList();
            dgvMembers.DataContext = m_memberList;
        }
        #endregion

        #region Filtering
        private void FilterList()
        {
            List<Member> newList = new List<Member>();

            foreach(Member m in m_memberList)
            {
                bool nameOK = false;
                bool yearOK = false;
                bool cityOK = false;
                bool favoriteOK = false;

                if (txtName.Text.Length == 0 || m.Name.ToUpper().Contains(txtName.Text.ToUpper()))
                    nameOK = true;
                else
                    continue;

                if (txtYear.Text.Length == 0 || m.Year.ToUpper().Contains(txtYear.Text.ToUpper()))
                    yearOK = true;
                else
                    continue;

                if (txtCity.Text.Length == 0 || m.City.ToUpper().Contains(txtCity.Text.ToUpper()))
                    cityOK = true;
                else
                    continue;

                if (chkOnlyFavorite.IsChecked == null || !(bool)chkOnlyFavorite.IsChecked || m.Favorite == 1)
                    favoriteOK = true;

                if (nameOK && yearOK && cityOK && favoriteOK)
                    newList.Add(m);
            }

            dgvMembers.DataContext = newList;
        }

        private void txtName_TextChanged(object sender, TextChangedEventArgs e)
        {
            FilterList();
        }

        private void txtYear_TextChanged(object sender, TextChangedEventArgs e)
        {
            FilterList();
        }

        private void txtCity_TextChanged(object sender, TextChangedEventArgs e)
        {
            FilterList();
        }

        private void chkOnlyFavorite_Click(object sender, RoutedEventArgs e)
        {
            FilterList();
        }
        #endregion

        #region MainPicture
        private void LoadMainPicture()
        {
            int index = rdn.Next(0, (m_memberList.Count - 1));
            LoadMainPicture(index, -2);
        }

        private void LoadMainPictureData(string picture,string name,string year,string color,string city,string modifications)
        {
            try
            {
                string sUri = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("TestAlbum.exe", "") + "\\" + picture;
                Uri src = new Uri(sUri, UriKind.RelativeOrAbsolute);
                imgMainPicture.Source = new BitmapImage(src);
            }
            catch (System.Exception ex)
            {
                imgMainPicture.Source = null;
            }

            lblMainPictureMemberName.Content = name;
            lblMainPictureYear.Content = year;
            lblMainPictureColor.Content = color;
            lblMainPictureCity.Content = city;
            lblMainPictureModifications.Content = modifications;
        }

        /// <summary>
        /// Load all the data to show in the MainPicture area
        /// </summary>
        /// <param name="in_memberIndex">the index of the member</param>
        /// <param name="in_pictureIndex">the index of the picture. -2 show a random picture</param>
        private void LoadMainPicture(int in_memberIndex, int in_pictureIndex)
        {
            bool hasPicture = false;
            int index = 0;

            if (in_memberIndex == m_memberList.Count)
                index = 0;
            else if (in_memberIndex < 0)
                index = (m_memberList.Count - 1);
            else
                index = in_memberIndex;
                

            while (!hasPicture)
            {           
                shownMemberIndex = index;

                Member m = m_memberList[index];

                if (m.PictureList.Count > 0)
                {
                    int pictureIndex = 0;

                    if(in_pictureIndex == -2)
                        pictureIndex = rdn.Next(0, (m.PictureList.Count - 1));
                    else
                    {
                        if (in_pictureIndex == m.PictureList.Count)
                            pictureIndex = 0;
                        else if (in_pictureIndex < 0)
                            pictureIndex = (m.PictureList.Count - 1);
                        else
                            pictureIndex = in_pictureIndex;
                    }

                    shownMemberPictureIndex = pictureIndex;

                    string pictureToShow = m.PictureList[pictureIndex];

                    LoadMainPictureData(pictureToShow, m.Name, m.Year, m.Color, m.City, m.ModificationStringFormatted);

                    hasPicture = true;
                }

                if (index < (m_memberList.Count - 1))
                    index++;
                else
                    index = 0;
            }
        }        

        private void imgPrevMember_MouseUp(object sender, MouseButtonEventArgs e)
        {
            LoadMainPicture(shownMemberIndex - 1,-2);
        }

        private void imgRdnMember_MouseUp(object sender, MouseButtonEventArgs e)
        {
            LoadMainPicture();
        }

        private void imgNextMember_MouseUp(object sender, MouseButtonEventArgs e)
        {
            LoadMainPicture(shownMemberIndex + 1, -2);
        }

        private void imgPrevPic_MouseUp(object sender, MouseButtonEventArgs e)
        {
            LoadMainPicture(shownMemberIndex, shownMemberPictureIndex -1 );
        }

        private void imgNextPic_MouseUp(object sender, MouseButtonEventArgs e)
        {
            LoadMainPicture(shownMemberIndex, shownMemberPictureIndex + 1);
        }
        #endregion

        #region Member Selection
        private void dgvMembers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dgvMembers.SelectedItems.Count <= 0)
                return;

            string memberName = ((Member)dgvMembers.Items[dgvMembers.SelectedIndex]).Name;

            LoadMainPicture(GetMemberIndex(memberName), -2);
        }

        /// <summary>
        /// Return the index of the first member with the name equal to the one pass in parameter
        /// </summary>
        /// <param name="memberName">name of the member that you want the index</param>
        /// <returns>the member index or -1 if none found</returns>
        private int GetMemberIndex(string memberName)
        {
            int index = -1;

            for (int i = 0; i < m_memberList.Count; i++)
            {
                if (m_memberList[i].Name == memberName)
                {
                    index = i;
                    break;
                }
            }

            return index;
        }
        #endregion

        #region Member Data Modification
        private void chkFavoriteSelected_Click(object sender, RoutedEventArgs e)
        {
            if (dgvMembers.SelectedItems.Count <= 0)
                return;

            Member member = ((Member)dgvMembers.Items[dgvMembers.SelectedIndex]);
            member.Favorite = Convert.ToInt32(!member.FavoriteBool);
            member.Save();

            LoadList();
            FilterList();
        }
        #endregion

        #region Form Customization
        private void LoadLogoData()
        {
            string logo;
            string logoText;

            Tools.GetLogoData(out logo, out logoText);

            lblLogoText.Content = logoText;

            if (logo != "")
            {
                try
                {
                    string sUri = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("TestAlbum.exe", "") + "\\" + logo;
                    Uri src = new Uri(sUri, UriKind.RelativeOrAbsolute);
                    imgLogo.Source = new BitmapImage(src);

                    logoBorder.Visibility = Visibility.Visible;
                }
                catch
                {
                    imgLogo.Source = null;
                    logoBorder.Visibility = Visibility.Hidden;
                }
            }
            else
            {
                imgLogo.Source = null;
                logoBorder.Visibility = Visibility.Hidden;
            }
        }
        #endregion

        #region Database Update
        BackgroundWorker worker;

        private void StartUpdate()
        {
            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;

            worker.DoWork += delegate(object s, DoWorkEventArgs args)
            {
                args.Result = UpdateDataWorker();
            };

            worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
            {
                bool updated = (bool)args.Result;

                if (updated)
                {
                    lblDBVersion.Content += Tools.DatabaseVersion;

                    MessageBoxResult response = MessageBox.Show("La base de donnée à été mise à jour." + Environment.NewLine
                        + "Voulez-vous afficher les nouvelles données ?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question);

                    if (response == MessageBoxResult.Yes)
                        LoadList();
                }
            };
            
            //run the process then show the progress dialog
            worker.RunWorkerAsync();
        }

        private bool UpdateDataWorker()
        {
            try
            {
                string folder;
                string file;
                string picFolder;

                Tools.GetUpdateFolder(out folder, out file, out picFolder);
                return Tools.Updater(Tools.GetDatabaseFile, Tools.GetPicturePath, folder, file, picFolder);

                
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Erreur lors de la mise à jour :" + ex.Message, "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return false;
        }

        #endregion

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if(worker.IsBusy)
                worker.CancelAsync();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            StartUpdate();
        }
    }
}
